package top.xtcoder.jdcbase.rbac.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.beetl.sql.core.SQLManager;
import org.nutz.dao.Cnd;
import org.nutz.dao.Dao;
import org.nutz.dao.QueryResult;
import org.nutz.dao.entity.Record;
import org.nutz.dao.pager.Pager;
import org.nutz.lang.Lang;
import org.nutz.lang.Strings;
import org.nutz.lang.random.R;
import org.nutz.lang.util.NutMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.StpUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import top.xtcoder.jdcbase.base.common.Funs;
import top.xtcoder.jdcbase.base.core.CreateOp;
import top.xtcoder.jdcbase.base.core.Resp;
import top.xtcoder.jdcbase.base.core.UserType;
import top.xtcoder.jdcbase.base.redis.PrRedisKey;
import top.xtcoder.jdcbase.base.redis.RedisCache;
import top.xtcoder.jdcbase.base.service.AccountService;
import top.xtcoder.jdcbase.base.vo.auth.PwdLoginVo;
import top.xtcoder.jdcbase.rbac.entity.AdminInfo;
import top.xtcoder.jdcbase.rbac.entity.AdminRole;
import top.xtcoder.jdcbase.rbac.entity.Role;
import top.xtcoder.jdcbase.rbac.params.AdminRoleRelaParam;
import top.xtcoder.jdcbase.rbac.service.PbRbacAccountService;
import top.xtcoder.jdcbase.rbac.service.PbRbacPermissionService;
import top.xtcoder.jdcbase.rbac.vo.MenuLoginResult;
import top.xtcoder.jdcbase.rbac.vo.PermVo;

@Api(tags = "管理员模块")
@RestController
@RequestMapping("/jdcbase/prrbac/system/admin")
public class PrRbacAdminController {
	private final static Logger log = LoggerFactory.getLogger(PrRbacAdminController.class);
	@Autowired
	private Dao dao;
	
	@Autowired
	private SQLManager sqlManager;
	
	@Autowired
	private PbRbacAccountService accountService;
	
	@Autowired
	private PbRbacPermissionService permissionService;

	@Autowired
	private RedisCache redisCache;
	
	@Value("${prrbac.login.checkVrcode:true}")
	private boolean checkVrcode;
	
	@ApiOperation("账号密码登陆")
	@PostMapping("/pwdLogin")
	public Resp<MenuLoginResult> pwdLogin(@Valid @RequestBody PwdLoginVo dto
			, HttpServletRequest request, HttpServletResponse response) {
		if(!checkVrcode) {
			log.info("验证码检查关闭");
		}
		String key = PrRedisKey.PB_PHOTO_VRCODE(Lang.getIP(request) + dto.getTimestamp());
		String code = redisCache.getCacheObject(key);
		log.info("取一条=>" + key + ": " + code);
		if(checkVrcode && !Strings.equals(code, dto.getVrcode())) {
			log.info("code=" + code);
			log.info("dto.getCode=" + dto.getVrcode());
			return Resp.ERROR("验证码不正确");
		}
		
		try {
			MenuLoginResult loginInfo = accountService.pwdLogin2(UserType.Admin.type, AdminInfo.class, request, dto);
			if(loginInfo.getMenus() == null || loginInfo.getMenus().size() <= 0) {
				return Resp.ERROR("你没有任何菜单权限");
			}
			response.setHeader(StpUtil.getTokenName(), StpUtil.getTokenValue());
			return Resp.OK("登陆成功",loginInfo);
		}catch(Exception e) {
			e.printStackTrace();
			return new Resp().error(e.getMessage());
		}
	}
	
	@ApiOperation(value ="关联/取消关联角色")
	@PostMapping("/roleSet")
	public Resp<String> roleSet(@Valid @RequestBody AdminRoleRelaParam urp){
		try{
            List<AdminRole> AdminRoles=dao.query(AdminRole.class,Cnd.where("adminid", "=", urp.getAdminid()));
            dao.delete(AdminRoles);
            
            // Set去重
			HashSet<String> set=new HashSet<>();
            for(String str : urp.getRoleids()){
                if(!Strings.isBlank(str)){
                	set.add(str);
                }
            }
			if(set!=null && set.size()>0){
				for(String s : set){
					AdminRole AdminRole=new AdminRole();
					AdminRole.setRoleid(s);
					AdminRole.setAdminid(urp.getAdminid());
					AdminRole.setCreatetime(new Date());
					AdminRole.setUpdatetime(new Date());
					AdminRole.setId(Funs.getId());
					dao.insert(AdminRole);
				}
			}
            return Resp.OK("操作成功！");
        }catch (Exception ex){
			ex.printStackTrace();
			return Resp.ERROR("异常信息[" + ex.getMessage() + "]");
		}
	}
	
	@ApiOperation("查看用户的角色")
	@GetMapping("/roles")
	public Resp<List<Role>> roles(
			@ApiParam("用户id 默认为当前用户")@RequestParam(value = "userid",defaultValue = "") String userid){
		if(Strings.isBlank(userid)){
			userid=StpUtil.getLoginId().toString().substring(1);
		}

		Set<String> roleIds = new HashSet();
		List<AdminRole> rps = dao.query(AdminRole.class
				, Cnd.where("isdelete", "=", 0)
				.and("userid", "=", userid));
		List<String> andInStrs=new ArrayList<String>();
		andInStrs.add("");
		rps.forEach(item->{
			andInStrs.add(item.getRoleid());
		});
		
		List<Role> query = dao.query(Role.class,
				Cnd.where("isdelete", "=", 0)
						.and("state", "=", 1).and(Cnd.cri().where().andInStrList("id",andInStrs)).asc("sort"));

//		for(int i = 0; rps != null && i < rps.size();i ++) {
//			roleIds.add(rps.get(i).getRoleid());
//		}
//		for(int i = 0; i < query.size(); i ++) {
//			if(roleIds.contains(query.get(i).getId())) {
//				Role item = query.get(i);
//				query.set(i, item);
//			}
//		}
		return Resp.OBJ_Q(query);
	}
	
//	@ApiOperation("加载后台框架数据，左侧菜单，网站title, logo等")
//	@GetMapping("/loadLayout")
//	public Resp<NutMap> loadLayout(
//			@ApiParam("用户id 默认为当前用户")@RequestParam(name="id", defaultValue = "") String id) {
//		NutMap permMap = permissionService.getPermSetByUserid(id);
//		Set<String> permIds = permMap.getAs("permIds", Set.class);
//		Map<String, List<String>> permBtnMap = permMap.getAs("permBtnMap", Map.class);
//		List<PermVo> permVo = permissionService.loadLeftMenu(permIds, permBtnMap, "0");
//		return new Resp().ok("获取成功").data(NutMap.NEW()
//			.addv("leftMenus", permVo));
//	}

	@ApiOperation("登录退出")
	@GetMapping("/logout")
	public Resp<NutMap> logout() {
		String loginId = StpUtil.getLoginId().toString();
		StpUtil.logout();
		return new Resp().ok("成功退出").data(NutMap.NEW()
				.addv("loginId", loginId));
	}

	@ApiOperation("账号信息")
	@GetMapping("/getInfo")
	public Resp<NutMap> getInfo() {
		String loginId = StpUtil.getLoginId().toString().substring(1);
		String loginType=StpUtil.getLoginId().toString().substring(0,1);
		AdminInfo teacherInfo=dao.fetch(AdminInfo.class, Cnd.where("id","=",loginId));
		return new Resp().ok("获取管理员信息").data(teacherInfo);
	}

	@ApiOperation("账号密码重设")
	@GetMapping("/setPwd")
	public Resp setPwd(@ApiParam("旧密码(需md5加密)") @RequestParam("oldPwd") String oldPwd,
					   @ApiParam("新密码(需md5加密)") @RequestParam("newPwd") String newPwd){
		String loginId = StpUtil.getLoginId().toString().substring(1);
		String loginType=StpUtil.getLoginId().toString().substring(0,1);
		return accountService.setPwd(AdminInfo.class, oldPwd, newPwd, loginId);
	}
	
	@ApiOperation(value = "添加信息")
	@PostMapping("/addOrUpdate")
    public Resp<AdminInfo> addOrUpdate(@Valid @RequestBody AdminInfo data){
		if(Strings.isNotBlank(data.getId())) {
			int c = dao.count(AdminInfo.class, Cnd.where("isdelete", "=", 0)
					.and("id", "!=", data.getId())
					.and("account", "=", data.getAccount()));
			if(c > 0) {
				return Resp.ERROR("帐号已存在");
			}
		}
		if(Strings.isNotBlank(data.getPassword())) {
			data.setSalt(R.captchaChar(6));
			data.setPassword(Funs.pwdEncry(data.getPassword(), data.getSalt()));
		}
		data.setUsertype(UserType.Admin.type);
        data = (@Valid AdminInfo) data.insertOrUpdate(dao);
        return Resp.OBJ_O(data);
    }

	@ApiOperation(value = "删除信息")
	@DeleteMapping("/delete")
    public Resp delete(@Valid @RequestParam(name = "id")String id){
		AdminInfo data = dao.fetch(AdminInfo.class, id);
		if(data == null) {
			return Resp.ERROR("数据已被删除");
		}
		if(data.isSuper()) {
			return Resp.ERROR("超级管理员，禁止删除");
		}
		int num = data.deletedSoft(dao);
		return Resp.OBJ_O(num);
    }
	
	@ApiOperation(value = "根据ID获取信息")
	@GetMapping("/byid")
    public Resp byid(@RequestParam(name = "id")String id){
		AdminInfo data = dao.fetch(AdminInfo.class, id);
		return Resp.OBJ_Q(data);
    }
	
	@ApiOperation(value = "列表信息")
	@GetMapping("/list")
    public Resp list(@RequestParam(defaultValue = "1")int page
			, @RequestParam(defaultValue = "20")int limit){
        
		
    	Cnd cnd = Cnd.where("isdelete", "=", 0);
    	Pager pager = dao.createPager(page, limit);
    	pager.setRecordCount(dao.count(AdminInfo.class, cnd));
    	List<AdminInfo> list = dao.query(AdminInfo.class, cnd, pager);
        
    	return Resp.OK("查询成功", new QueryResult(list, pager));
    }
	
}
